#include "fepch.h"
#include "ViewCamera.h"
#include "FysicsEngine/Scene/Scene.h"

#include <glm/gtc/matrix_transform.hpp>

namespace Fysics
{
	ViewCamera::ViewCamera(float fov, glm::vec3 position)
		: m_Position(position), WorldUp(0,1,0), m_Up(0, 1, 0), Fov(fov),
		m_Pitch(glm::radians(15.0f)), m_Yaw(glm::radians(180.0f))
	{
		m_ProjectionMatrix = glm::perspective(glm::radians(fov), 16.f / 9.f, 0.1f, 100.f);
		
		m_Direction.x = glm::cos(m_Pitch) * glm::sin(m_Yaw);
		m_Direction.y = glm::sin(m_Pitch);
		m_Direction.z = glm::cos(m_Pitch) * glm::cos(m_Yaw);

		Right = glm::normalize(glm::cross(m_Direction, WorldUp));
		m_Up = glm::normalize(glm::cross(Right, m_Direction));

		RecalculateViewMatrix();
	}

	void ViewCamera::SetPosition(const glm::vec3& position)
	{
		m_Position = position;
	}

	void ViewCamera::SetFov(float fov)
	{
		if (fov >= 1.0f && fov <= 75.0f)
			Fov = fov;
		if (fov <= 1.0f)
			Fov = 1.0f;
		if (fov >= 75.0f)
			Fov = 75.0f;
	}

	void ViewCamera::RecalculateViewMatrix()
	{
		m_ViewMatrix = glm::lookAt(m_Position, m_Position + m_Direction, WorldUp);
	}

	void ViewCamera::RecalculateProjectionMatrix()
	{
		m_ProjectionMatrix = glm::perspective(glm::radians(Fov), 16.f / 9.f, 0.1f, 100.f);
	}

	void ViewCamera::CalculateViewMatrix()
	{
		m_ViewMatrix = glm::translate(glm::mat4(1.0f), m_Position);
	}

	void ViewCamera::UpdateCameraVectors() {
		m_Direction.x = glm::cos(m_Pitch) * glm::sin(m_Yaw);
		m_Direction.y = glm::sin(m_Pitch);
		m_Direction.z = glm::cos(m_Pitch) * glm::cos(m_Yaw);
		Right = glm::normalize(glm::cross(m_Direction, WorldUp));
		m_Up = glm::normalize(glm::cross(m_Direction, Right));
	}

	void ViewCamera::ProcessMouseMovement(float deltaX, float deltaY) {
		m_Pitch -= glm::radians(deltaY);
		m_Yaw -=   glm::radians(deltaX);

		if (m_Pitch > glm::radians(89.0f))
			m_Pitch = glm::radians(89.0f);
		if (m_Pitch < glm::radians(-89.0f))
			m_Pitch = glm::radians(-89.0f);

		if (m_Yaw >= glm::radians(360.f))
			m_Yaw = 0;
		else if (m_Yaw <= 0)
			m_Yaw = glm::radians(360.f);

		UpdateCameraVectors();
	}

}
